//weak hybrid template
//$Id: weak_hybrid.h 678 2011-02-27 18:14:42Z Oleg.Bulychov $
#pragma once

template<class TSolver0, class TSolver1, class CheckPoint>
class weak_hybrid
{
    TSolver0 solver0_;
    TSolver1 solver1_;
public:
    typedef typename TSolver1::TEnvironment   TEnvironment;

    static char const* get_Name()
    { 
        static std::string name;
        if (0 == name.length())
        {
            name = TSolver0::get_Name();
            name += "_";
            name += TSolver1::get_Name();
        }
        return name.c_str();
    }

    static char const* get_Section()
    {
        return "/";//:root xml node
    }

    random_generator& get_Rnd() { return solver0_.get_Rnd(); }

    template<class V>
    void accept(V& v)
    {
        v(solver0_);
        v(solver1_);
    }

    void init(TEnvironment* env, int rank, int thread_id, bool debug_flag = false)
    {
        solver0_.init(env, rank, thread_id, debug_flag);
        solver1_.init(env, rank, thread_id, debug_flag);
    }

    TEnvironment* get_Environment() const { return solver0_.get_Environment(); }

    template<class TInOutSolution, class TStatistics>
    void solve(Solution_Pool<TInOutSolution>& pool, TStatistics& stat)
    {
        solver0_.solve(pool, stat);
        
        if (!CheckPoint::check(solver0_, pool))
            return;

        solver1_.solve(pool, stat);
    }

    template<class TInOutSolution, class TStatistics, class Comm>
    void solve(Solution_Pool<TInOutSolution>& pool, TStatistics& stat, Comm& comm)
    {
        solver0_.solve(pool, stat, comm);
        
        if (!CheckPoint::check(solver0_, pool))
            return;

        solver1_.solve(pool, stat, comm);
    }
};

//EOF!
